# Copyright (c) 2013, 2015-2016 Ruslan Baratov, Alexandre Pretyman
# All rights reserved.

cmake_minimum_required(VERSION 3.0)
project(Hunter)

include(ExternalProject) # ExternalProject_Add

include("@HUNTER_SELF@/cmake/Hunter")

include(hunter_internal_error)
include(hunter_report_broken_package)
include(hunter_status_debug)
include(hunter_assert_not_empty_string)

hunter_status_debug("Scheme: url_sha1_qt")

# Check preconditions
hunter_assert_not_empty_string("@HUNTER_SELF@")
hunter_assert_not_empty_string("@HUNTER_EP_NAME@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_URL@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_SHA1@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_COMPONENT@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_DOWNLOAD_DIR@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_BUILD_DIR@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_CONFIGURATION_TYPES@")
hunter_assert_not_empty_string("@HUNTER_CONFIG_ID_PATH@")
hunter_assert_not_empty_string("@HUNTER_INSTALL_PREFIX@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_INSTALL_PREFIX@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_LICENSE_DIR@")
hunter_assert_not_empty_string("@HUNTER_Qt_VERSION@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_SETUP_DIR@")
hunter_assert_not_empty_string("@HUNTER_GLOBAL_SCRIPT_DIR@")
hunter_assert_not_empty_string("@HUNTER_TLS_VERIFY@")

set(HUNTER_Qt_VERSION "@HUNTER_Qt_VERSION@")

if("@MSVC@")
  hunter_assert_not_empty_string("@HUNTER_MSVC_ARCH@")
  hunter_assert_not_empty_string("@HUNTER_MSVC_VCVARSALL@")
  hunter_assert_not_empty_string("@HUNTER_MSVC_YEAR@")
endif()

if("@MSVC@")
  set(env_cmd "@HUNTER_MSVC_VCVARSALL@" "@HUNTER_MSVC_ARCH@")
  hunter_status_debug("Environment command: ${env_cmd}")
else()
  # Workaround for: http://public.kitware.com/Bug/view.php?id=15567
  set(env_cmd "@CMAKE_COMMAND@" -E echo "configure")
endif()

if(WIN32)
  set(configure_command "configure.bat")
else()
  set(configure_command "./configure")
endif()

set(configure_opts)

list(APPEND
    configure_opts
      -confirm-license
      -nomake examples
      -nomake tests
)

string(COMPARE NOTEQUAL "@QT_COMMERCIAL@" "" _is_qt_commercial)
if(_is_qt_commercial)
  list(APPEND
      configure_opts
        -commercial
  )
else() # is standard opensource
  list(APPEND
      configure_opts
        -opensource
  )
endif()

set(HUNTER_PATCH_QT_MACX_CLANG FALSE)
set(HUNTER_QT_OS_IS_LINUX FALSE)

string(COMPARE EQUAL "@CMAKE_OSX_SYSROOT@" "iphoneos" _is_iphoneos)
string(COMPARE NOTEQUAL "@ANDROID@" "" _is_android)
string(COMPARE EQUAL "@CMAKE_SYSTEM_NAME@" "Linux" _is_linux)
string(COMPARE EQUAL "@CMAKE_SYSTEM_NAME@" "Darwin" _is_darwin)
#insert windows test here
if(_is_iphoneos)
  list(APPEND
      configure_opts
        -xplatform macx-ios-clang
  )

  string(COMPARE NOTEQUAL "@IPHONESIMULATOR_ARCHS@" "" has_sim)
  string(COMPARE NOTEQUAL "@IPHONEOS_ARCHS@" "" has_dev)

  if(has_sim AND NOT has_dev)
    list(APPEND configure_opts -sdk iphonesimulator)
  elseif(has_dev AND NOT has_sim)
    list(APPEND configure_opts -sdk iphoneos)
  else()
    # build both, no extra options
  endif()
elseif(_is_android)
  if(NOT BUILD_SHARED_LIBS)
    hunter_user_error("Static variant of Qt is not supported")
  endif()

  hunter_assert_not_empty_string("${CMAKE_ANDROID_NDK}")
  hunter_assert_not_empty_string("${CMAKE_ANDROID_ARCH_ABI}")
  hunter_assert_not_empty_string("${CMAKE_SYSTEM_VERSION}")

  #setup the android ndk options
  hunter_add_package(Android-SDK)
  list(APPEND
    configure_opts
      -xplatform android-g++
      -android-sdk "${ANDROID-SDK_ROOT}/android-sdk"
      -android-ndk "${CMAKE_ANDROID_NDK}"
      -android-ndk-platform "android-${CMAKE_SYSTEM_VERSION}"
      -android-arch "${CMAKE_ANDROID_ARCH_ABI}"
      # -android-toolchain-version # ???
      -no-warnings-are-errors
  )

  # Hint: directory ${CMAKE_ANDROID_NDK}/prebuilt
  if(CMAKE_HOST_APPLE)
    list(APPEND configure_opts -android-ndk-host "darwin-x86_64")
  elseif(CMAKE_HOST_UNIX)
    list(APPEND configure_opts -android-ndk-host "linux-x86_64")
  elseif(CMAKE_HOST_WIN32)
    list(APPEND configure_opts -android-ndk-host "windows-x86_64")
  else()
    hunter_internal_error("Can't detect host")
  endif()
elseif(_is_darwin)
  list(APPEND
    configure_opts
      -no-framework
      -no-dbus
      # Do not forget to update qt-configure if other platform support needed
      # (follow HUNTER_PATCH_QT_MACX_CLANG)
      -platform macx-clang
  )
  set(HUNTER_PATCH_QT_MACX_CLANG TRUE)
elseif(_is_linux)
  set(HUNTER_QT_OS_IS_LINUX TRUE)
  hunter_add_package(drm)
  hunter_add_package(ice)
  hunter_add_package(sm)
  hunter_add_package(x11)
  hunter_add_package(xcb)
  hunter_add_package(xcursor)
  hunter_add_package(xdamage)
  hunter_add_package(xext)
  hunter_add_package(xfixes)
  hunter_add_package(xrender)
  hunter_add_package(xshmfence)
  hunter_add_package(xxf86vm)

  string(COMPARE EQUAL "${X11_ROOT}" "${XCB_ROOT}" is_good)
  if(NOT is_good)
    hunter_internal_error("Roots not the same")
  endif()

  string(COMPARE EQUAL "${XEXT_ROOT}" "${XCB_ROOT}" is_good)
  if(NOT is_good)
    hunter_internal_error("Roots not the same")
  endif()

  string(COMPARE EQUAL "${XRENDER_ROOT}" "${XCB_ROOT}" is_good)
  if(NOT is_good)
    hunter_internal_error("Roots not the same")
  endif()

  string(COMPARE EQUAL "${SM_ROOT}" "${XCB_ROOT}" is_good)
  if(NOT is_good)
    hunter_internal_error("Roots not the same")
  endif()

  string(COMPARE EQUAL "${ICE_ROOT}" "${XCB_ROOT}" is_good)
  if(NOT is_good)
    hunter_internal_error("Roots not the same")
  endif()

  list(APPEND
    configure_opts
      -qt-xcb
      -opengl desktop
      -L "${XCB_ROOT}/lib"
      -I "${XCB_ROOT}/include"
  )
elseif("@MSVC@")
  list(APPEND configure_opts -platform "win32-msvc@HUNTER_MSVC_YEAR@")
  if(QT_OPENGL_DESKTOP)
    list(APPEND configure_opts -opengl "desktop")
  endif()
elseif("@MINGW@")
  list(APPEND configure_opts -platform "win32-g++")
  list(APPEND configure_opts -opengl "desktop")
endif()

if(QT_WITH_GSTREAMER)
  hunter_add_package(gst_plugins_bad)
  hunter_add_package(gst_plugins_good)
  hunter_add_package(gst_plugins_ugly)

  list(APPEND configure_opts -gstreamer 1.0)
endif()

if(HUNTER_STATUS_DEBUG AND NOT WIN32)
  list(APPEND configure_opts "-verbose")
endif()

if(BUILD_SHARED_LIBS)
  list(APPEND configure_opts "-shared")
else()
  list(APPEND configure_opts "-static")
  if("@MSVC@" AND NOT QT_BUILD_DYNAMIC_VSRUNTIME)
    list(APPEND configure_opts "-static-runtime")
  endif()
endif()

list(APPEND configure_opts "-prefix" "@HUNTER_PACKAGE_INSTALL_PREFIX@")

### Disable SQL {
# Configuration should be predictable on different machines. It must not
# depends on what SQL packages installed on building machine and what not.
# This will simplify building errors analyzing and allow to use cache from
# CI slave.
# Right way to turn this features ON is to add this packages to Hunter and
# pass location of libraries to Qt.
list(APPEND configure_opts "-no-sql-db2")
list(APPEND configure_opts "-no-sql-ibase")
list(APPEND configure_opts "-no-sql-mysql")
list(APPEND configure_opts "-no-sql-oci")
list(APPEND configure_opts "-no-sql-odbc")
list(APPEND configure_opts "-no-sql-psql")
list(APPEND configure_opts "-no-sql-sqlite2")
# list(APPEND configure_opts "-no-sql-sqlite") # (okay, bundled copy)
list(APPEND configure_opts "-no-sql-tds")
### }

### Predictable configuration {
# Disable components that may or may not present in system (TODO: add to Hunter)
if(NOT _is_android AND NOT _is_iphoneos)
  if(_is_linux)
    # EGL needed for QML/qtdeclarative (Linux)
    # Not needed for OSX, error for Windows
    list(APPEND configure_opts "-egl")
    list(APPEND configure_opts "-eglfs")
  endif()
  # Needed for component 'qtdeclarative' and Qt5Quick module (tested on Linux)
  # list(APPEND configure_opts "-no-opengl")
endif()
list(APPEND configure_opts "-no-fontconfig")
list(APPEND configure_opts "-no-gif")
if(NOT WIN32)
  list(APPEND configure_opts "-no-glib")
  if(HUNTER_Qt_VERSION VERSION_LESS 5.9)
    list(APPEND configure_opts "-no-gtkstyle")
  endif()
  if(HUNTER_Qt_VERSION VERSION_LESS 5.12)
    list(APPEND configure_opts "-no-xinput2")
  endif()
endif()
list(APPEND configure_opts "-no-icu")
list(APPEND configure_opts "-no-openssl")
### }

### Predictable configuration {
# Force bundled copy (TODO: add to Hunter)
list(APPEND configure_opts "-qt-freetype")
list(APPEND configure_opts "-qt-harfbuzz")
list(APPEND configure_opts "-qt-libjpeg")
list(APPEND configure_opts "-qt-libpng")
list(APPEND configure_opts "-qt-pcre")
if(NOT WIN32)
  if(HUNTER_Qt_VERSION VERSION_LESS 5.12)
    list(APPEND configure_opts "-qt-xkbcommon")
  else()
    list(APPEND configure_opts "-xkbcommon")
  endif()
endif()
list(APPEND configure_opts "-qt-zlib")
### }

### Configuration type --

set(cfg "@HUNTER_PACKAGE_CONFIGURATION_TYPES@")

string(COMPARE EQUAL "${cfg}" "Release" is_release)
string(COMPARE EQUAL "${cfg}" "Debug" is_debug)
string(COMPARE EQUAL "${cfg}" "Release;Debug" is_str_release_debug)
string(COMPARE EQUAL "${cfg}" "Debug;Release" is_str_debug_release)

if(is_str_release_debug OR is_str_debug_release)
  set(is_release_debug TRUE)
else()
  set(is_release_debug FALSE)
endif()

if(is_release)
  list(APPEND configure_opts "-release")
elseif(is_debug)
  list(APPEND configure_opts "-debug")
elseif(is_release_debug)
  if(NOT APPLE AND NOT WIN32)
    hunter_user_error(
        "Qt debug+release is available only on Mac/Win32 platforms"
    )
  endif()
  list(APPEND configure_opts "-debug-and-release")
else()
  hunter_user_error("Qt configuration type `${cfg}` is not supported")
endif()

### -- end

hunter_status_debug("Qt configure options (without -skip): ${configure_opts}")

list(APPEND configure_command ${configure_opts})

if(ANDROID)
  set(ANDROID_API_VERSION "android-${CMAKE_SYSTEM_VERSION}")
else()
  set(ANDROID_API_VERSION "")
endif()

set(qt_component "@HUNTER_PACKAGE_COMPONENT@")
set(hunter_self "@HUNTER_SELF@")
set(global_install_dir "@HUNTER_INSTALL_PREFIX@")
set(local_install_dir "@HUNTER_PACKAGE_INSTALL_PREFIX@")

set(build_opts)
string(COMPARE NOTEQUAL "@HUNTER_JOBS_OPTION@" "" have_jobs)
if(have_jobs AND NOT "@MSVC_IDE@")
  list(APPEND build_opts "-j" "@HUNTER_JOBS_OPTION@")
endif()

# We can't use HUNTER_PACKAGE_SOURCE_DIR since it will be removed after
# successful installation of component (we always need to have 'qtbase'
# component, no other components will be built without it).
# We optimize build time by not rebuilding qtbase every time (~ 30 min) but
# lose some extra HDD space. Example: Qt base + 2 components + sources ~ 4.4G
set(
    qt_source_dir
    "@HUNTER_CONFIG_ID_PATH@/QtBuild/@HUNTER_PACKAGE_INTERNAL_DEPS_ID@"
)

# We are building only one component "qt_component". To skip all other
# components we need to add extra '-skip' options. To get the list of components
# we need to find all directories in top of sources that starts with the 'qt*'.
# Since we have no sources at this moment we need to use a script on
# CONFIGURE_COMMAND stage. Also note that this script must not be located in
# 'qt_source_dir' since this directory will be removed while unpacking
# the archive. First create script in 'HUNTER_PACKAGE_BUILD_DIR' then copy
# it to 'qt_source_dir' on CONFIGURE_COMMAND stage.

# Used variables:
#   * configure_command
#   * qt_component
#   * hunter_self
#   * ANDROID
#   * IOS
#   * HUNTER_Qt_VERSION
#   * HUNTER_PATCH_QT_MACX_CLANG
#   * HUNTER_QT_OS_IS_LINUX
#   * global_install_dir
configure_file(
    "@HUNTER_PACKAGE_SETUP_DIR@/ep-stages/qt-configure.cmake.in"
    "@HUNTER_PACKAGE_BUILD_DIR@/qt-configure.cmake"
    @ONLY
)

# We are always building 'qtbase' component (alone or + one component), hence
# libraries from 'qtbase' will always be saved to cache archive. For space
# optimization reason files from 'qtbase' will be saved to file:
#   * <root-id>/Install/qtbase_installed_files.cmake
# Other components will exclude files from this list and install only
# necessary components (note that Qt is cacheable => we install libs to
# local HUNTER_PACKAGE_INSTALL_PREFIX before HUNTER_INSTALL_PREFIX).

# Used variables:
#   * global_install_dir
#   * local_install_dir
#   * qt_component
#   * hunter_self
#   * ANDROID_API_VERSION
#   * qt_source_dir
#   * ANDROID
#   * IOS
#   * HUNTER_Qt_VERSION
#   * HUNTER_QT_OS_IS_LINUX
#   * BUILD_SHARED_LIBS
configure_file(
    "@HUNTER_PACKAGE_SETUP_DIR@/ep-stages/qt-install.cmake.in"
    "@HUNTER_PACKAGE_BUILD_DIR@/qt-install.cmake"
    @ONLY
)

# Used variables:
#  * ANDROID
#  * ANDROID_API_VERSION
#  * build_opts
#  * hunter_self
#  * is_release_debug
#  * is_release
#  * is_debug
#  * global_install_dir
#  * HUNTER_QT_OS_IS_LINUX
configure_file(
    "@HUNTER_PACKAGE_SETUP_DIR@/ep-stages/qt-build.cmake.in"
    "@HUNTER_PACKAGE_BUILD_DIR@/qt-build.cmake"
    @ONLY
)

# This file created after archive with sources successfully
# downloaded and unpacked
if(EXISTS "${qt_source_dir}/qt-configure.cmake")
  set(download_step DOWNLOAD_COMMAND "@CMAKE_COMMAND@" -E echo "skip download")
else()
  set(download_step)
endif()

if("@HUNTER_PACKAGE_LOG_BUILD@")
  set(log_build 1)
else()
  set(log_build 0)
endif()

if("@HUNTER_PACKAGE_LOG_INSTALL@")
  set(log_install 1)
else()
  set(log_install 0)
endif()

ExternalProject_Add(
    "@HUNTER_EP_NAME@"
    URL
    @HUNTER_PACKAGE_URL@
    URL_HASH
    SHA1=@HUNTER_PACKAGE_SHA1@
    DOWNLOAD_DIR
    "@HUNTER_PACKAGE_DOWNLOAD_DIR@"
    TLS_VERIFY
    "@HUNTER_TLS_VERIFY@"
    SOURCE_DIR
    "${qt_source_dir}"
    INSTALL_DIR
    "@HUNTER_PACKAGE_INSTALL_PREFIX@"
        # not used, just avoid creating Install/<name> empty directory
    ${download_step}
    CONFIGURE_COMMAND
    ${env_cmd}
    COMMAND
        "@CMAKE_COMMAND@"
        -E copy
        "@HUNTER_PACKAGE_BUILD_DIR@/qt-configure.cmake"
        "${qt_source_dir}/qt-configure.cmake"
    COMMAND
        "@CMAKE_COMMAND@" -P "${qt_source_dir}/qt-configure.cmake"
    BUILD_COMMAND
    ${env_cmd}
    COMMAND
        "@CMAKE_COMMAND@"
        -E copy
        "@HUNTER_PACKAGE_BUILD_DIR@/qt-build.cmake"
        "${qt_source_dir}/qt-build.cmake"
    COMMAND
        "@CMAKE_COMMAND@" -P "${qt_source_dir}/qt-build.cmake"
    BUILD_IN_SOURCE
    1
    INSTALL_COMMAND
    ${env_cmd}
    COMMAND
        "@CMAKE_COMMAND@"
        -E copy
        "@HUNTER_PACKAGE_BUILD_DIR@/qt-install.cmake"
        "${qt_source_dir}/qt-install.cmake"
    COMMAND
        "@CMAKE_COMMAND@" -P "${qt_source_dir}/qt-install.cmake"
    COMMAND # Copy license files
        "@CMAKE_COMMAND@"
        "-C@HUNTER_ARGS_FILE@" # for 'HUNTER_INSTALL_LICENSE_FILES'
        "-Dsrcdir=@HUNTER_PACKAGE_SOURCE_DIR@"
        "-Ddstdir=@HUNTER_PACKAGE_LICENSE_DIR@"
        -P
        "@HUNTER_SELF@/scripts/try-copy-license.cmake"
    LOG_BUILD ${log_build}
    LOG_INSTALL ${log_install}
)
